﻿using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.EnhancedTouch;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
#endif

namespace Jinndev {

    public class ZoomHelper : MonoBehaviour {

        public delegate void OnZoomDelegate(ZoomHelper helper, float value);
        public OnZoomDelegate onZoom;

        public float smooth = 10f;             //平滑度
        public float sensitivity = 20f;      //灵敏度

        public float minValue = 1f;
        public float maxValue = 10f;

        public bool reverse = false;

        public float value { get; private set; }
        public float targetValue { get; private set; }

        private float touchDistance = 0;

        private void Awake() {
#if ENABLE_INPUT_SYSTEM
            if (Mouse.current != null) {
            }
            else if (Touchscreen.current != null && !EnhancedTouchSupport.enabled) {
                EnhancedTouchSupport.Enable();
            }
#endif
        }

        private void Update() {
#if ENABLE_INPUT_SYSTEM
            if (Touchscreen.current != null) {
                var touches = Touch.activeTouches;
                if (touches.Count > 1) {
                    var touch1 = touches[0];
                    var touch2 = touches[1];
                    if (touch1.phase == UnityEngine.InputSystem.TouchPhase.Began || touch2.phase == UnityEngine.InputSystem.TouchPhase.Began) {
                        touchDistance = Vector2.Distance(touch1.screenPosition, touch2.screenPosition);
                    }
                    else if (touch1.phase == UnityEngine.InputSystem.TouchPhase.Moved || touch2.phase == UnityEngine.InputSystem.TouchPhase.Moved) {
                        float distance = Vector2.Distance(touch1.screenPosition, touch2.screenPosition);
                        float delta = distance - touchDistance;
                        touchDistance = distance;
                        OnZoom(delta * sensitivity);
                    }
                }
            }
            else if (Mouse.current != null) {
                Vector2 scroll = Mouse.current.scroll.ReadValue();
                if (scroll.y != 0) {
                    OnWheelZoom(scroll.y);
                }
            }
#else
            if (Input.mousePresent) {
                float wheel = Input.GetAxis("Mouse ScrollWheel");
                if (wheel != 0) {
                    OnWheelZoom(wheel);
                }
            }
            if (Input.touchSupported && Input.touchCount > 1) {
                var touch1 = Input.GetTouch(0);
                var touch2 = Input.GetTouch(1);
                if (touch1.phase == UnityEngine.TouchPhase.Began || touch2.phase == UnityEngine.TouchPhase.Began) {
                    touchDistance = Vector2.Distance(touch1.position, touch2.position);
                }
                else if (touch1.phase == UnityEngine.TouchPhase.Moved || touch2.phase == UnityEngine.TouchPhase.Moved) {
                    float distance = Vector2.Distance(touch1.position, touch2.position);
                    float delta = distance - touchDistance;
                    touchDistance = distance;
                    OnZoom(delta * sensitivity);
                }
            }
#endif

            if (!CommonUtil.Approximately(value, targetValue, 0.002f)) {
                value = Mathf.Lerp(value, targetValue, smooth * Time.deltaTime);
                if (onZoom != null) {
                    onZoom.Invoke(this, value);
                }
            }
        }

        public void SetZoom(float zoom) {
            targetValue = zoom;
            value = zoom;
        }

        public void ResetZoom() {
            touchDistance = 0;
            targetValue = 0;
            value = 0;
        }

        private void OnWheelZoom(float wheel) {
            OnZoom(wheel * 100 * sensitivity);
        }

        private void OnZoom(float delta) {
            float zoom = value + (reverse ? -1 : 1) * delta * Time.deltaTime;
            targetValue = Mathf.Clamp(zoom, minValue, maxValue);
        }

    }

}
